package com.btcode.orm.conver;

import com.btcode.exception.MsgException;
import com.btcode.orm.exception.ValueConveException;
import com.btcode.orm.model.IField;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DefaultValueConver implements IValueConver, Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    /**
     * 保证simpleDateFormat线程安全
     */
    private static ThreadLocal<SimpleDateFormat> sfPool = new ThreadLocal<SimpleDateFormat>();

    @Override
    public Object conveToSQLValue(IField field, Object value) {

        if (field == null) {
            throw new MsgException("field不能为空", null);
        }

        try {
            switch (field.getFieldType()) {
                case BigDecimal:
                    return converToBigdecimal(value);
                case Date:
                    return converToSQLDate(value);
                case DateTime:
                    return converToSQLTimestamp(value);
                case Double:
                    return converToDouble(value);
                case Integer:
                    return converToInteger(value);
                case String:
                    return converToString(value);
                case Timestamp:
                    return converToSQLTimestamp(value);
                default:
                    throw new MsgException("不支持" + field.getFieldType() + "类型的转换", null);
            }
        }
        catch (Exception e) {
            String valueType = null;

            if (value != null) {
                valueType = value.getClass().toString();
            }

            throw new ValueConveException(
                "类型:" + valueType + ",值:" + value + ",转成为SQLValue类型:" + field.getFieldType() + "出错",
                e);
        }

    }

    @Override
    public Object conveToORMValue(IField field, Object value) {

        if (field == null) {
            throw new MsgException("field不能为空", null);
        }

        try {
            switch (field.getFieldType()) {
                case BigDecimal:
                    return converToBigdecimal(value);
                case Date:
                    return converToDate(value);
                case DateTime:
                    return converToDate(value);
                case Double:
                    return converToDouble(value);
                case Integer:
                    return converToInteger(value);
                case String:
                    return converToString(value);
                case Timestamp:
                    return converToSQLTimestamp(value);
                default:
                    throw new MsgException("不支持" + field.getFieldType() + "类型的转换", null);
            }
        }
        catch (Exception e) {

            String valueType = null;

            if (value != null) {
                valueType = value.getClass().toString();
            }

            throw new ValueConveException(
                "表：" + field.getTableName() + ",字段：" + field.getFieldName() + ",类型:" + valueType
                    + ",值:" + value + ",转成为ORMValue类型:" + field.getFieldType() + "出错", e);
        }

    }

    private BigDecimal converToBigdecimal(Object value) {
        return (BigDecimal) value;
    }

    private Integer converToInteger(Object value) {
        Integer result = null;
        if (value == null) {
            return null;
        }
        if (value instanceof Integer) {
            result = (Integer) value;
        }
        else {
            try {
                String regEx = "([0-9]+)";
                Pattern p = Pattern.compile(regEx);
                Matcher m = p.matcher(value.toString());
                m.find();
                result = Integer.parseInt(m.group());
            }
            catch (Exception e) {

            }
        }
        return result;
    }

    private String converToString(Object value) {
        if (value == null) {
            return null;
        }

        return value.toString();
    }

    private Double converToDouble(Object value) {
        Double result = null;
        if (value == null) {
            return null;
        }
        if (value instanceof Double) {
            result = (Double) value;
        }
        else {
            try {
                result = Double.parseDouble(value.toString());
            }
            catch (Exception e) {
                throw new MsgException("类型转换失败", e);
            }
        }
        return result;
    }

    private java.sql.Date converToSQLDate(Object value) throws Exception {
        Date utilDate = converToDate(value);

        if (value == null) {
            return null;
        }

        java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());

        return sqlDate;
    }

    private Date converToDate(Object value) throws Exception {
        Date result = null;

        if (value == null) {
            return null;
        }

        if (value instanceof Date) {
            result = (Date) value;
        }
        else if (value instanceof java.sql.Date) {
            java.sql.Date sqlDate = (java.sql.Date) value;
            result = new Date(sqlDate.getTime());
        }
        else if (value instanceof Timestamp) {
            Timestamp timestamp = (Timestamp) value;
            result = new Date(timestamp.getTime());
        }
        else if (value instanceof Long) {
            Long lvalue = new Long(value.toString());
            result = new Date(lvalue);
        }
        else if (value instanceof Double) {
            long lvalue = ((Double)value).longValue();
            result = new Date(lvalue);
        }
        else if (value instanceof BigDecimal) {
            BigDecimal lvalue = (BigDecimal) value;
            result = new Date(lvalue.longValue());
        }
        else if (value instanceof Integer) {
            Integer ivalue = (Integer)value;
            result = new Date(ivalue.longValue());
        }
        else if(value instanceof byte[]){
            //兼容sqlserver中的timestamp类型，该类型读到java中就是byte[]，同时这种数据并非时间，而是计数器，所以没有业务意义
        }
        else {
            try {
                try{
                    SimpleDateFormat sf = sfPool.get();
                    if (sf == null) {
                        sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        sfPool.set(sf);
                    }
                    result = sf.parse(value.toString());
                }
                catch (Exception e){
                    long longValue = Long.parseLong(value.toString());
                    result = new Date(longValue);
                }
            }
            catch (Exception e) {
                throw new MsgException("类型转换失败", e);
            }
        }
        return result;
    }

    /**
     * Timestamp类型的 共用一个
     */
    private Timestamp converToSQLTimestamp(Object value) throws Exception {
        Date dateResult = converToDate(value);
        if (dateResult == null) {
            return null;
        }
        Timestamp result = new Timestamp(dateResult.getTime());
        return result;
    }

}
